//
//  VocAppController.m
//  GREVocab2007
//
//  Created by Wallace Wu on 09-1-12.
//  Copyright 2009 __MyCompanyName__. All rights reserved.
//

#import "VocAppController.h"
#import "VOCWordList.h"
#import "VOCWordExp.h"

@implementation FuncPair

@synthesize string;
@synthesize function;

-(id)initWithString:(NSString*)aString WithFunction:(VOCWORDFunction)aFunction
{
    self = [super init];
    if(self)
    {
        self.string = aString;
        self.function = aFunction;
    }
    return self;
}

-(void)dealloc
{
    [string release];
    [super dealloc];
}

@end

@implementation VocAppController
-(void)reencoding
{
    for (NSString *file in [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[textSourcePath stringValue] error:NULL]) {
        NSError *error = nil;
        NSString *string = [NSString stringWithContentsOfFile:[[textSourcePath stringValue] stringByAppendingPathComponent:file] encoding:CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGBK_95) error:&error];
        
        if(error)
        {
            [[NSAlert alertWithError:error] runModal];
        }
        
        error = nil;
        [string writeToFile:[[textSourcePath stringValue] stringByAppendingPathComponent:file] atomically:YES encoding:NSUTF8StringEncoding error:&error];
        if(error)
        {
            [[NSAlert alertWithError:error] runModal];
        }
        NSLog(@"%@", file);
    }
}

-(NSString *)trimBracketsAndWhitespacesAndNewLine:(NSString*)string
{
    NSMutableString *ret = [[string mutableCopy] autorelease];
    NSRange start = [string rangeOfString:@"["];
    NSRange end = [string rangeOfString:@"]"];
    
    while (start.location != NSNotFound) {
        [ret deleteCharactersInRange:NSMakeRange(start.location, end.location-start.location+1)];
        start = [ret rangeOfString:@"["];
        end  = [ret rangeOfString:@"]"];
    }
    
    return [ret  stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}

-(NSMutableArray*)generateMixArray:(NSMutableArray*)input
{
    NSMutableArray *tmp = [[[NSMutableArray alloc] init] autorelease];
    NSUInteger i, count = [input count];
    for (i = 0; i < count; i++) {
        for (int j = i+1; j < count; j++) {
            VOCWORDFunction func = ((FuncPair*)[input objectAtIndex:i]).function |((FuncPair*)[input objectAtIndex:j]).function;
            NSString *output = [NSString stringWithFormat:@"%@/%@", ((FuncPair*)[input objectAtIndex:i]).string , ((FuncPair*)[input objectAtIndex:j]).string];
            [tmp addObject:[[[FuncPair alloc] initWithString:output WithFunction:func] autorelease]];
            output = [NSString stringWithFormat:@"%@/%@", ((FuncPair*)[input objectAtIndex:j]).string , ((FuncPair*)[input objectAtIndex:i]).string ];
            [tmp addObject:[[[FuncPair alloc] initWithString:output WithFunction:func] autorelease]];
        }
    }
    
    [tmp addObjectsFromArray:input];
    
    return tmp;
}

-(NSArray*)parseChinese:(NSString *)explanation
{
    NSString *noun = @"n.";
    NSString *verb = @"v.";
    NSString *adj = @"adj.";
    NSString *adj2 = @"a.";
    NSString *adv = @"adv.";
    NSString *conj = @"conj.";
    NSString *interj =@"interj.";
    
    NSMutableArray *result = [[[NSMutableArray alloc] init] autorelease];
    NSMutableArray *stringToMatch = [[[NSMutableArray alloc] init] autorelease];
    [stringToMatch addObject:[[[FuncPair alloc] initWithString:noun WithFunction:VOC_WORD_FUNC_NOUN] autorelease]];
    [stringToMatch addObject:[[[FuncPair alloc] initWithString:verb WithFunction:VOC_WORD_FUNC_VERB] autorelease]];
    [stringToMatch addObject:[[[FuncPair alloc] initWithString:adj WithFunction:VOC_WORD_FUNC_ADJ] autorelease]];
    [stringToMatch addObject:[[[FuncPair alloc] initWithString:adj2 WithFunction:VOC_WORD_FUNC_ADJ] autorelease]];
    [stringToMatch addObject:[[[FuncPair alloc] initWithString:adv WithFunction:VOC_WORD_FUNC_ADV] autorelease]];
    [stringToMatch addObject:[[[FuncPair alloc] initWithString:conj WithFunction:VOC_WORD_FUNC_CONJ] autorelease]];
    [stringToMatch addObject:[[[FuncPair alloc] initWithString:interj WithFunction:VOC_WORD_FUNC_CONJ] autorelease]];
    
    stringToMatch = [self generateMixArray:stringToMatch];
    
    //start parsing from beginning, assume there is two explanations at most for each word
    
    FuncPair *pair;
    NSRange foundRange,newFoundRange;
    
    for (int i = 0; i < [stringToMatch count]; i++) {
        pair = ((FuncPair*)[stringToMatch objectAtIndex:i]);
        NSString *headMatch = pair.string;
        foundRange = [explanation rangeOfString:headMatch];
        if(foundRange.location ==0)
        {
            break;
        }
    }
    
    if(foundRange.location !=0)
    {
        //[[NSAlert alertWithMessageText:@"Error" defaultButton:nil alternateButton:nil otherButton:nil informativeTextWithFormat:@"%@ is a bad formatted string",explanation] runModal];
        NSLog(@"%@ is a bad formatted string",explanation);
        return result;
    }
       
    // this is the supposed good situation
    VOCWordExp *exp = [[[VOCWordExp alloc] init] autorelease];
    exp.kind = VOC_WORD_LANG_CHINESE;
    exp.function = pair.function;
    
    //find if there is more explanations
    NSRange moreRange = NSMakeRange(foundRange.location+foundRange.length, [explanation length]-foundRange.length);
    
    for (int j = 0; j < [stringToMatch count]; j++) {
        pair = ((FuncPair*)[stringToMatch objectAtIndex:j]);
        NSString *bodyMatch = pair.string;
        newFoundRange = [explanation rangeOfString:bodyMatch options:NSCaseInsensitiveSearch range:moreRange];
        
        if(newFoundRange.location != NSNotFound)
        {
            break;
        }
    }
    
    if(newFoundRange.location ==NSNotFound)
    {
        exp.explanation = [explanation substringFromIndex:NSMaxRange(foundRange)];
    }
    else
    {
        exp.explanation = [explanation substringWithRange:NSMakeRange(NSMaxRange(foundRange), newFoundRange.location - NSMaxRange(foundRange))];
           
        //process the next explanation
        VOCWordExp *another = [[[VOCWordExp alloc] init] autorelease];
        another.kind = VOC_WORD_LANG_CHINESE;
        another.function = pair.function;
        another.explanation = [explanation substringFromIndex:NSMaxRange(newFoundRange)];
        [result addObject:another];
    }
    
    //push into result
    [result addObject:exp];
    
    return [[result copy] autorelease];
}

- (NSArray*) parseSingleFile: (NSString *) sourcePath  {
    
    NSMutableArray *result = [[[NSMutableArray alloc] init] autorelease];
    
    //start to parse and store the values
    NSError *error = nil;
    NSString *string = [NSString stringWithContentsOfFile:sourcePath encoding:NSUTF8StringEncoding error:&error];
    
    if(error)
    {
        [[NSAlert alertWithError:error] runModal];
    }
    NSArray *array  = [string componentsSeparatedByString:@"\n"];
    for (int i = 0; i < [array count]-1;) {
        NSRange foundRange = [[array objectAtIndex:i] rangeOfString:@"[00:00.00]"];
        NSString *english = [self trimBracketsAndWhitespacesAndNewLine:[array objectAtIndex:i]];
        
        if([english length] == 0 || foundRange.location != NSNotFound)
        {
            i++;
            continue;
        }
        NSString *chinese = [self trimBracketsAndWhitespacesAndNewLine:[array objectAtIndex:i+1]];
        
        NSCharacterSet *nonEnglishCharacters = [[NSCharacterSet letterCharacterSet] invertedSet];
        
        NSScanner *englishScanner = [NSScanner scannerWithString:english];
        if([englishScanner scanCharactersFromSet:nonEnglishCharacters intoString:NULL])
        {
            NSLog(@"Warning!, found non-english letter in word %@", [englishScanner string]);
        }
        
        //parse function from chinese
        NSArray *exps = [self parseChinese:chinese];
        
        VOCWordData *oneWord = [[VOCWordData alloc] initWithWord:english withExplanations:exps withKind:VOC_WORD_LANG_ENGLISH];
        [result addObject:oneWord];
        [oneWord release];

        i+=2;
    }
    
    return [[result copy] autorelease];
}

-(void)verifyData:(VOCWordList*)list
{
    NSLog(@"Start verifing...there is %d words in list %@", [list.data count], list.name);
    
    NSMutableCharacterSet *englishSet = [[[NSCharacterSet whitespaceAndNewlineCharacterSet] mutableCopy] autorelease];
    
    [englishSet removeCharactersInString:@"n.avdj"];
    NSCharacterSet *nonEnglishCharacters = [[NSCharacterSet letterCharacterSet] invertedSet];
    for (VOCWordData* word in list.data) {
        NSScanner *englishScanner = [NSScanner scannerWithString:word.word];
        if([englishScanner scanCharactersFromSet:nonEnglishCharacters intoString:NULL])
        {
            NSLog(@"Warning!, found non-english letter in word %@", [englishScanner string]);
        }
        
        for (VOCWordExp *exp in word.explanations) {
            NSString *output;
            NSScanner *nonEnglishScanner = [NSScanner scannerWithString:exp.explanation];
            if([nonEnglishScanner scanCharactersFromSet:englishSet intoString:&output])
            {
                NSLog(@"Warning!, found english letters %@ in word %@", output, [nonEnglishScanner string]);
            }
        }
    }
    NSLog(@"Verifing done...");
}

-(IBAction)import:(id)sender
{
    NSString *sourcePath = [textSourcePath stringValue];
    
    //NSString *chinese,*english;
    
    NSMutableArray *data = [[NSMutableArray alloc] init];
    VOCWordList *list = [[VOCWordList alloc] init];
    list.name = @"GRE HongBao 2007";
    for (NSString *file in [[NSFileManager defaultManager] contentsOfDirectoryAtPath:sourcePath error:NULL]) {
        [data addObjectsFromArray:[self parseSingleFile:[sourcePath stringByAppendingPathComponent:file]]];
    }
    list.data = data;
    [data release];
    
    
    [self verifyData:list];
    
    [NSKeyedArchiver archiveRootObject:list toFile:[@"~/HongBao2007" stringByStandardizingPath]];
//    for(NSString *line in array)
//    {
//        //process each line
//        NSRange start = [line rangeOfString:@"["];
//        NSRange end = [line rangeOfString:@"]"];
//        
//        NSRange englishRange = {
//            0,start.location
//        };
//        english = [[line substringWithRange:englishRange] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
//        
//        NSRange chineseRange = {
//            end.location+1,[line length]-end.location-1
//        };
//        chinese = [line substringWithRange:chineseRange];
//        VOCWordData *word = [[VOCWordData alloc] initWithWord:english withExplanations:[NSDictionary dictionaryWithObjectsAndKeys:chinese,TypeChinese,nil] withKind:TypeEnglish];
//        [data addObject:word];
//        [word release];
//    }
//    [textSourcePath setAttributedStringValue:[NSKeyedUnarchiver unarchiveObjectWithFile:@"/data"]];
    
//    NSString *path = [[NSString stringWithString:@"~/webster.html"] stringByStandardizingPath];
//    NSData *data = [NSData dataWithContentsOfFile:path];
//    WebPreferences *pref = [WebPreferences standardPreferences];
//    NSLog(@"%d",[pref defaultFontSize]);
//    [pref setDefaultFontSize:14];
//    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:pref,NSWebPreferencesDocumentOption,nil];
//    NSDictionary *settings;
//    NSAttributedString *attrString = [[NSAttributedString alloc] initWithHTML:data options:options documentAttributes:&settings];
//    NSLog(@"%@",settings);
//    [textSourcePath setAttributedStringValue:[attrString string]];
    
//    id str=[[NSMutableAttributedString alloc] initWithString:@"test attributed" attributes:[NSDictionary dictionaryWithObjectsAndKeys:[NSColor redColor], NSForegroundColorAttributeName,nil]];
//    [str appendAttributedString:[[NSAttributedString alloc] initWithString:@"test append" attributes:[NSDictionary dictionaryWithObjectsAndKeys:[NSColor blueColor], NSForegroundColorAttributeName,nil]]];
//    [textSourcePath setAttributedStringValue:str];
    //[NSKeyedArchiver archiveRootObject:data toFile:[[NSString stringWithString:@"~/data"] stringByStandardizingPath]];

//    id data = [NSKeyedUnarchiver unarchiveObjectWithFile:@"/data"];
//    NSLog(@"%@",data);
        
    //[data release];
}

-(IBAction)open:(id)sender
{
    NSOpenPanel *openPanel = [NSOpenPanel openPanel];
    [openPanel setCanChooseFiles:YES];
    [openPanel setCanChooseDirectories:YES];
    [openPanel setDelegate:self];
        
    if([openPanel runModal] == NSOKButton)
    {
        [textSourcePath setStringValue:[openPanel filename]];
    }
}

@end
